/*
 *   Copyright (c) 2010-2022, SIUFUNG
 */
package net.siufung.market.base.permit.service.impl;

import cn.hutool.core.text.StrPool;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.siufung.core.model.enums.DeletedEnum;
import net.siufung.market.base.permit.enums.PermitTypes;
import net.siufung.market.base.permit.mapper.IMenuMapper;
import net.siufung.market.base.permit.mapper.IPermitMapper;
import net.siufung.market.base.permit.mapper.entity.Menu;
import net.siufung.market.base.permit.mapper.entity.Permit;
import net.siufung.market.base.permit.service.IPermitService;
import net.siufung.mybatis.base.BaseServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 系统权限表 数据服务实现
 *
 * @author 陈建峰
 * @since 2022-07-05 22:19:50
 */
@Slf4j
@AllArgsConstructor
@Service(value = "permitService")
@Transactional(rollbackFor = Exception.class)
public class PermitServiceImpl extends BaseServiceImpl<IPermitMapper, Permit> implements IPermitService {

    private final IMenuMapper menuMapper;

    @Override
    public void updateBatchByMenuId(Integer menuId, List<Permit> permitList) {
        Menu menu = menuMapper.selectById(menuId);
        List<String> paramsOfSign = permitList.stream().map(Permit::getSign)
                .collect(Collectors.toList());
        List<Permit> updatePermitList = Lists.newArrayList();
        List<Permit> allPermitList = getBaseMapper().selectList(Wrappers.query());
        List<String> allPermitCodeList = allPermitList.stream()
                .map(Permit::getPermitCode).collect(Collectors.toList());
        /*
          1.找出数据库中已经存在的数据
         */
        List<Permit> memoryPermitList = allPermitList.stream()
                .filter(element -> PermitTypes.BUTTON.getValue().equals(element.getPermitType())
                        && menuId.equals(element.getMenuId()))
                .collect(Collectors.toList());
//        List<Permit> memoryPermitList = getBaseMapper().selectList(new LambdaQueryWrapper<Permit>()
//                .eq(Permit::getMenuId, menu.getId()).isNotNull(Permit::getParentId)
//                .ne(Permit::getSign, menu.getSign()));
        /*
         * 2.找出在数据库中禁用的并且在传参中，有则释放、更新
         */
        List<Permit> recoverPermitList = memoryPermitList.stream()
                .filter(systemPermit -> systemPermit.getDeleted() && paramsOfSign.contains(systemPermit.getSign()))
                .collect(Collectors.toList());
        if(ObjectUtil.isNotEmpty(recoverPermitList)){
            for (Permit recoverPermit: recoverPermitList) {
                for (Permit paramPermit: permitList) {
                    if(StrUtil.equals(paramPermit.getSign(), recoverPermit.getSign())){
                        recoverPermit.setText(paramPermit.getText());
                        recoverPermit.setPermitName(StrUtil.concat(true,
                                menu.getMenuName(), StrPool.DASHED, recoverPermit.getText()));
                        break;
                    }
                }
                recoverPermit.setDeleted(DeletedEnum.NOT.getValue());
                updatePermitList.add(recoverPermit);
            }
        }
        /*
         * 3.找出在数据库中并且在传参中的,有则更新
         */
        List<Permit> renewalPermitList = memoryPermitList.stream()
                .filter(systemPermit -> paramsOfSign.contains(systemPermit.getSign()))
                .collect(Collectors.toList());
        if(ObjectUtil.isNotEmpty(renewalPermitList)){
            for (Permit renewalPermit: renewalPermitList) {
                for (Permit paramPermit: permitList) {
                    if(StrUtil.equals(paramPermit.getSign(), renewalPermit.getSign())){
                        renewalPermit.setText(paramPermit.getText());
                        renewalPermit.setPermitName(StrUtil.concat(true,
                                menu.getMenuName(), StrPool.DASHED, renewalPermit.getText()));
                        break;
                    }
                }
                updatePermitList.add(renewalPermit);
            }
        }
        /*
         * 4.找出在数据库列表中并且不存在传参中的，有则禁止
         */
        List<Permit> disabledPermitList = memoryPermitList.stream()
                .filter(systemPermit -> !paramsOfSign.contains(systemPermit.getSign()))
                .collect(Collectors.toList());
        if(ObjectUtil.isNotEmpty(disabledPermitList)){
            for (Permit disabledPermit: disabledPermitList) {
                disabledPermit.setDeleted(DeletedEnum.IS.getValue());
                updatePermitList.add(disabledPermit);
            }
        }
        /*
         * 5.找出存在传参中并且不存在数据列表中的，有则存储
         */
        List<String> memoryPermitOfSignList = memoryPermitList.stream()
                .map(Permit::getSign).collect(Collectors.toList());
        List<Permit> insertPermitList = permitList.stream()
                .filter(systemPermitDto -> !memoryPermitOfSignList.contains(systemPermitDto.getSign()))
                .collect(Collectors.toList());
        if(ObjectUtil.isNotEmpty(insertPermitList)){
            int sequence = 0;
            Permit usablePermit;
            Integer permitParentId;
            if(ObjectUtil.isEmpty(memoryPermitList)){
                usablePermit = getBaseMapper().selectOne(
                        new LambdaQueryWrapper<Permit>()
                                .eq(Permit::getMenuId, menu.getId()).isNull(Permit::getParentId));
                permitParentId = usablePermit.getId();
            } else {
                usablePermit = memoryPermitList.get(memoryPermitList.size() - 1);
                permitParentId = usablePermit.getParentId();
                sequence = usablePermit.getSequence();
            }
            String permitCode;
            for (Permit insertPermit: insertPermitList) {
                insertPermit.setPermitName(StrUtil.concat(true,
                        menu.getMenuName(), StrPool.DASHED, insertPermit.getText()));
                insertPermit.setParentId(permitParentId);
                insertPermit.setMenuId(menu.getId());
                permitCode = this.getRandomPermitCode(8, allPermitCodeList);
                allPermitCodeList.add(permitCode);
                insertPermit.setPermitCode(permitCode);
                insertPermit.setPermitType(PermitTypes.BUTTON.getValue());
                insertPermit.setBusinessType(menu.getBusinessType());
                sequence++;
                insertPermit.setSequence(sequence);
            }
        }
        /*
         * 6.结果处理
         */
        if(ObjectUtil.isEmpty(paramsOfSign)){
            super.update(new LambdaUpdateWrapper<Permit>()
                    .eq(Permit::getMenuId, menu.getId())
                    .set(Permit::getDeleted, DeletedEnum.IS.getValue()));
        }
        if(ObjectUtil.isNotEmpty(updatePermitList)){
            super.updateBatchById(updatePermitList);
        }
        if(ObjectUtil.isNotEmpty(insertPermitList)){
            super.saveBatch(insertPermitList);
        }
    }

    @Override
    public String getRandomPermitCode(int length, List<String> allPermitCodeList){
        String permitCode = RandomUtil.randomString(length);
        if(allPermitCodeList.contains(permitCode)){
            permitCode = getRandomPermitCode(length, allPermitCodeList);
        }
        return permitCode;
    }
}